/*
 * SmartCam master processor library
 * Coprocessor mapping determination.
 */

#ifndef __MAPPING_H_INCLUDED
#define __MAPPING_H_INCLUDED

#ifdef __cplusplus
extern "C" {
#endif

#include <scu.h>
#include "settings.h"

/*
>> Note that evaldeps.c and the simulator will assume unicasting over
>> *all* nodes, whereas reality will only unicast over self-routing nodes.
>> Furthermore, unicasting is not supported by evaluate.c
*/
//#define MULTICAST

enum {SCM_MIN, SCM_MAX, SCM_OLD_MIN, SCM_OLD_MAX, SCM_NUM_FLOWTYPES};

typedef struct scm_op_s
{
  int id, fixed, _id, affinity;

  struct scm_proc_s *processor;
  table_t streams;               /* scm_stream_t, referenced for ops, owned for bench */
  table_t arguments; /* scm_arg_t, owned */
  
  double fraction[SCM_NUM_FLOWTYPES];            /* min, max */
  int    state;

  scs_operation_t *operation;
  scs_target_operation_t *target_operation;
} scm_op_t;

typedef struct scm_proc_s
{
  table_t operations;            /* scm_op_t, referenced, indexed */
  table_t streams;               /* scm_stream_t, referenced, indexed */
  table_t routes;                /* scm_proclist_t, owned, indexed by destination->id */
  table_t resources;             /* scm_resource_t, owned, indexed */

  sc_proc_t *processor;
  scs_target_t *target;
  scs_target_operation_t *transport_operation;
} scm_proc_t;

typedef struct scm_proclist_s
{
  scm_proc_t *proc;
  struct scm_proclist_s *next;
} scm_proclist_t;

typedef struct scm_resource_s
{
  int count;
  scs_target_resource_t *target_resource;
} scm_resource_t;

typedef struct scm_transport_s
{
  scm_proc_t *source, *destination;
  int streams;
} scm_transport_t;

typedef struct scm_arg_s
{
  int bulk;
  struct scm_op_s *operation;
} scm_arg_t;

typedef struct scm_stream_s
{
  int id;
  struct scm_arg_s *producer;
  table_t consumers;             /* scm_arg_t, referenced */

  table_t processors;            /* scm_proc_t, referenced, indexed */
  table_t transports;            /* scm_transport_t, owned, indexed by destination->id */
  table_t alltransports;         /* scm_transport_t, owned, indexed by destination->id */

  unsigned long int bytes;
  double bandwidth[SCM_NUM_FLOWTYPES];           /* min, max */
  int    state;
} scm_stream_t;

void scMapInit(void);
void scMapReadAvailability(char *avfile);
void scMapReadBenchmarks(char *benchfile);
int scMapOperation(sc_op_t *o, int apply);
int scMapBuildCurrent(void);
int scMapAssignProcessor(scm_op_t *o, scm_proc_t *p);
int scMapAssignTransports(scm_stream_t *s);
void scMapAssignTransportsDirect(sc_var_t *s);
void scMapUnassignProcessor(scm_op_t *o);
void scMapUnassignTransports(scm_stream_t *s);
scm_op_t * scMapFindBenchmarkedOperation(scm_proc_t *p, scm_op_t *o);
void scMapDestroy(void);
int scMapIsOperationMappable(sc_op_t *so);
void scMapApplyProcessorAssignments(void);
void scMapApplyProcessorAssignment(sc_op_t *o, sc_proc_t *p);
void scMapApplyTransportAssignment(scm_stream_t *ms, sc_var_t *v);

#ifdef __cplusplus
}
#endif

#endif /* __MAPPING_H_INCLUDED */
